[imx6ull]I2C协议 |
您所在的位置:网站首页 › imx6ull pcb › [imx6ull]I2C协议 |
文章目录
一、I2C协议1.I2C物理层2.I2C协议层①起始位②I2C读写地址③I2C应答信号④数据位收发⑤总线速率⑥主机发送数据流程⑦主机接收数据流程
二、I2C接口使能三、SHT20采样测试1.硬件连接2.测试代码3.Makefile4.运行测试
一、I2C协议
I2C Bus(IIC,Inter-Integrated Circuit Bus) 是由Philips公司(现被NXP 收购)推出的一种在电子通信控制领域常用的通信协议。它由时钟线(SCL)和数据线(SDA)两根线构成通信线路,利用上拉电阻将它们拉成高电平(表示总线空闲), 其典型的电压准位为+3.3V或+5V,具有电路简单、连接线少、控制简单、通信速率高等优点。 1.I2C物理层在I2C总线上每一位数据都由一个同步时钟没冲所对应,也就是在SCL串行时钟的配合下,数据在SDA上从高位向低位一次串行传送每一位数据。I2C通信时序图如下: I2C 总线在空闲时SDA和SCL都处于高电平状态(由上拉电阻拉成高电平),当主设备要开始一次I2C通信时就发送一个START(S)信号,这个起始位就可以告诉所有I2C 从机,主设备需要开始进行 I2C 通信了;当要结束一次 I2C 通信时,则发送一个 STOP§信号结束本次通信。 首先在主机发送了起始信号后,第二个时序要给出通讯的目标从机的物理地址。并且I2C总线是一种能够实现半双工通信的同步串行通信协议,从主设备的角度来看具有读/写从设备的功能。 这时候I2C的读写地址如上图所示有8位(bit),其中有7bit为物理地址,还有1bit用于表示读/写方向。所以这样的I2C从设备读写通常是一个字节,其中高7位是上面描述的物理地址,最低位用来表示读写方向(0表示写操作,1表示读操作)。 ③I2C应答信号当主机往I2C总线上传输器件的地址时,所有的从机接受到了这个地址后与自己的地址相比较,如果相同则发送一个应答ACK信号,不相同则不发送 应答信号,当主机收到了应答信号后表示建立连接成功,而未收到则表示寻址失败(可以在总线时序的第九个时钟时的电平高低进行判断)。 主/从机在之后的数据通信中,数据接收方(可能是主机也可能是从机)收到传输的一个字节数据后,需要给出响应,此时处在第九个时钟,发送端释放 SDA 线控制权,将 SDA 电平拉高,由接收方控制。 若希望继续,则给出“应答(ACK, Acknowledge)”信号,即SDA 为低电平;若不希望继续,则给出“非应答(NACK,Not Acknowledge)”信号,即 SDA 为高电平;![]() 主机在收到从机的应答信号之后,开始给从机发送数据。SDA 数据线上的每个字节必须是 8 位,每次传输的字节数量没有限制,每个字节发送完成之后,从机必须跟一个应答信号。 I2C 总线通信时数据位传输采用MSB(最高位优先)方式发送,其中高电平表示数据位 1,低电平表示数据位 0。当传输的数据位需要改变时(如上一个位发送的是 1,下一个位要发送 0),必须发生在 SCL 为低电平期间。即规定所有设备在SCL高时候,进行数据的获取,SCL低时候,进行数据的变化。 I2C 总线是一种同步、半双工、采用电平信号收发的串行总线,其速率支持: 标准模式(Standard-mode):速率高达 100kbit/s快速模式(Fast-mode):速率高达 400kbit/s快速模式+(Fast-mode Plus):速率高达 1Mbit/s。高速模式(High-speed mode):速率高达 3.4Mbit/s超快速模式(Ultra Fast-mode):速率高达 5Mbit/s (单向传输时支持) ⑥主机发送数据流程主机在检测到总线为空闲时,发送一个启动信号“S”,开始一次通信的开始; 主机接着发送一个从设备地址,它由 7bit 物理地址和 1bit 读写控制位 R/W 组成(此时 R/W=0 写操作); 相对应的从机收到命令字节后向主机回馈应答信号 ACK(ACK=0); 主机收到从机的应答信号后开始发送第一个字节的数据; 从机收到数据后返回一个应答信号 ACK; 主机收到应答信号后再发送下一个数据字节; 主机发完最后一个字节并收到 ACK 后,向从机发送一个停止信号 P 结束本次通信并释放总线; 从机收到 P 信号后也退出与主机之间的通信; 主机发送启动信号后,接着发送地址字节(其中 R/W=1 读操作); 对应的从机收到地址字节后,返回一个应答信号并向主机发送数据; 主机收到数据后向从机反馈一个应答信号 ACK; 从机收到应答信号后再向主机发送下一个数据; 当主机完成接收数据后,向从机发送一个 NAK,从机收到非应答信号后便停止发送; 主机发送非应答信号后,再发送一个停止信号,释放总线结束通信; I.MX6ull有四个I2C外设,但是我们的IGKBoard开发板只使能了两路I2C外设,如下: I2C2 ---> 触摸屏控制器,rtc时钟,摄像头控制器 I2C1 ---> 40pin扩展口使用,由DToverlay进行开启 GPIO01_IO03 ---> I2C1_SDA GPIO01_IO03 ---> I2C1_SCL我们需要使能I2C1,所以我们需要和之前一样修改开发板的DTOverlay配置文件,添加管脚对I2C的支持,eMMC介质的boot分区下的config.txt的路径:/run/media/mmcblk1p1/config.txt 修改如下: # Enable I2C overlay dtoverlay_i2c1=yes重启后可以在/dev下查看I2C的设备节点是否存在,或者我们可以查看/sys/bus/i2c/devices中设备文件来查看I2C驱动是否加载: ls -l /dev/i2c-* ls /sys/bus/i2c/devices/
sht20.c /********************************************************************************* * Copyright: (C) 2023 Deng Yonghao * All rights reserved. * * Filename: sht20.c * Description: This file is SHT20 get temperature and humidity code * * Version: 1.0.0(2023年03月24日) * Author: Deng Yonghao * ChangeLog: 1, Release initial version on "2023年03月24日 20时52分18秒" * ********************************************************************************/ /* * Hardware connection: * * Sht20 Module RaspberryPi/IGKBoard * VCC 3.3V * SDA SDA * SCL SCL * GND GND */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define SOFTRESET 0xFE #define TRIGGER_TEMPERATURE_NO_HOLD 0xF3 #define TRIGGER_HUMIDITY_NO_HOLD 0xF5 static inline void msleep(unsigned long ms); static inline void dump_buf(const char *prompt, uint8_t *buf, int size); int sht2x_init(char *i2c_dev); int sht2x_get_serialnumber(int fd, uint8_t *serialnumber, int size); int sht2x_get_temp_humidity(int fd, float *temp, float *rh); int main(int argc, char **argv) { int fd; float temp; float rh; uint8_t serialnumber[8]; if( argc != 2) { printf("This program used to do I2C test by sht20 temperature & humidity module.\n"); printf("Usage: %s /dev/i2c-x\n", argv[0]); return 0; } fd = sht2x_init(argv[1]); if(fd printf("SHT2x get serial number failure\n"); return 3; } if( sht2x_get_temp_humidity(fd, &temp, &rh) struct timespec cSleep; unsigned long ulTmp; cSleep.tv_sec = ms / 1000; if (cSleep.tv_sec == 0) { ulTmp = ms * 10000; cSleep.tv_nsec = ulTmp * 100; } else { cSleep.tv_nsec = 0; } nanosleep(&cSleep, 0); } /* 打印 buf值*/ static inline void dump_buf(const char *prompt, uint8_t *buf, int size) { int i; if( !buf ) { return ; } if( prompt ) { printf("%s ", prompt); } for(i=0; i uint8_t buf[4]; if( fd int fd; if( (fd=open(i2c_dev, O_RDWR)) printf("SHT2x softreset failure\n"); return -2; } return fd; } /* 获取sht20的温度湿度值 */ int sht2x_get_temp_humidity(int fd, float *temp, float *rh) { uint8_t buf[4]; if( fd uint8_t buf[4]; if( fdCC} ${APP_NAME}.c -o ${APP_NAME} clean: @rm -f ${APP_NAME} 4.运行测试下载交叉编译后的可执行文件,并赋予它可执行权限: 然后运行程序,并可以向sht20传感器哈一口气,可以见得温湿度变化:
|
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |